import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'
import {allAsyncRoutes, constantRoutes, anyRoute} from '@/router/routes'
import cloneDeep from 'lodash/cloneDeep'

/* 
根据routes对allAsyncRoutes进行过滤生成用户的权限路由列表
allAsyncRoutes: 所有异步路由的数组
routeNames: 当前用户的权限路由标识名称的数组 ["Product", "Trademark", "Attr"]
*/
function filterAsyncRoutes(allAsyncRoutes, routeNames) {
    return allAsyncRoutes.filter(route => {

      // 如果route的name在routeNames中没有, 直接过滤掉
      if (routeNames.indexOf(route.name)===-1) return false

      // 如果当前route还有子路由(也就是有children), 需要对子路由也进行权限过滤
      if (route.children && route.children.length>0) {
        // 递归调用, 对子路由进行过滤产生子路由的列表, 并替换掉原本的children
        route.children = filterAsyncRoutes(route.children, routeNames)
      }

      return true
    })
}

const getDefaultState = () => {
  return {
    token: getToken(),
    name: '', // 用户名
    avatar: '', // 头像url
    roles: [], // 角色列表
    buttons: [], // 按钮权限列表
    routes: [] // 路由权限列表  => 用于显示左侧导航菜单(常量路由和异步路由)
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    // Object.assign(obj1, obj2) // 将obj2合并到obj1中
    Object.assign(state, getDefaultState()) // 重置状态数据
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },

  /* 
  保存用户及权限相关数据
  */
  SET_USER (state, {name, avatar, roles, buttons, asyncRoutes}) {
    state.name = name
    state.avatar = avatar
    state.roles = roles
    state.buttons = buttons
    state.routes = constantRoutes.concat(asyncRoutes)  // (常量路由和异步路由)
  }
}

const actions = {
  /* 
  登陆的异步action
  */
  login({ commit }, userInfo) {
    const { username, password } = userInfo
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password }).then(response => {
        const { data } = response
        commit('SET_TOKEN', data.token)
        setToken(data.token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  /* 
  获取用户信息的异步action
  */
  async getInfo({ commit }) {
    // 请求获取用户信息和权限数据
    const result = await getInfo()
    const {name, avatar, roles, buttons, routes} = result.data
    // console.log(name, avatar, roles, buttons, routes)

    // 根据routes对allAsyncRoutes进行过滤生成用户的权限路由列表
    /* 
    bug2: 切换用户登陆(A=>B), 只能看到B的部分权限路由页面(与A重合的部分)
      原因: 对所有权限路由进行过滤, 过滤掉部分子路由 => 不能修改allAsyncRoutes
      解决: 对allAsyncRoutes深拷贝一份再进行过滤处理 => 不会修改allAsyncRoutes
    */
    const asyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes), routes)
    console.log('---', asyncRoutes)
    
    // 动态注册权限路由和通配路由
    router.addRoutes([...asyncRoutes, anyRoute])
    // 保存用户及权限数据
    commit('SET_USER', {name, avatar, roles, buttons, asyncRoutes})
  },

  /* 
  退出登陆的异步action
  */
  // logout({ commit }) {
  //   return new Promise((resolve, reject) => {
  //     logout().then(() => {
  //       // 移除token
  //       removeToken()
  //       // 重置路由
  //       resetRouter()
  //       // 重置用户相关信息
  //       commit('RESET_STATE')
  //       resolve()
  //     }).catch(error => {
  //       reject(error)
  //     })
  //   })
  // },
  async logout ({commit}) {
    await logout()
    // 移除token
    removeToken()
    // 重置路由
    resetRouter()
    // 重置用户相关信息
    commit('RESET_STATE')
  },

  /* 
  重置token和用户信息的同步action
  */
  resetToken({ commit }) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

